package com.ideaaedi.springcloud.jd.user.config;

import cn.xuyanwu.spring.file.storage.FileStorageProperties;
import com.ideaaedi.springcloud.jd.commonds.exception.MinIOOperateException;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * minio配置
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.E
 */

@Slf4j
@Component
public class MinioConfig {
    
    @Resource
    private FileStorageProperties fileStorageProperties;
    
    @PostConstruct
    private void initMinioClient() throws Exception {
        for (FileStorageProperties.MinIO minConf : fileStorageProperties.getMinio()) {
            // 初始化MinioClient
            String endPoint = minConf.getEndPoint();
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(endPoint)
                    .credentials(minConf.getAccessKey(), minConf.getSecretKey())
                    .build();
            
            String bucket = minConf.getBucketName();
            // 保证桶存在
            if (!bucketExists(minioClient, bucket)) {
                log.warn("minio({}) bucket {} non-exist, auto create it.", endPoint, bucket);
                // 创建桶
                makeBucket(minioClient, bucket);
                String policy = String.format("{\n"
                        + "    \"Version\": \"2012-10-17\",\n"
                        + "    \"Statement\": [\n"
                        + "        {\n"
                        + "            \"Effect\": \"Allow\",\n"
                        + "            \"Principal\": {\n"
                        + "                \"AWS\": [\n"
                        + "                    \"*\"\n"
                        + "                ]\n"
                        + "            },\n"
                        + "            \"Action\": [\n"
                        + "                \"s3:GetBucketLocation\",\n"
                        + "                \"s3:ListBucketMultipartUploads\"\n"
                        + "            ],\n"
                        + "            \"Resource\": [\n"
                        + "                \"arn:aws:s3:::%s\"\n"
                        + "            ]\n"
                        + "        },\n"
                        + "        {\n"
                        + "            \"Effect\": \"Allow\",\n"
                        + "            \"Principal\": {\n"
                        + "                \"AWS\": [\n"
                        + "                    \"*\"\n"
                        + "                ]\n"
                        + "            },\n"
                        + "            \"Action\": [\n"
                        + "                \"s3:ListBucket\"\n"
                        + "            ],\n"
                        + "            \"Resource\": [\n"
                        + "                \"arn:aws:s3:::%s\"\n"
                        + "            ],\n"
                        + "            \"Condition\": {\n"
                        + "                \"StringEquals\": {\n"
                        + "                    \"s3:prefix\": [\n"
                        + "                        \"*\"\n"
                        + "                    ]\n"
                        + "                }\n"
                        + "            }\n"
                        + "        },\n"
                        + "        {\n"
                        + "            \"Effect\": \"Allow\",\n"
                        + "            \"Principal\": {\n"
                        + "                \"AWS\": [\n"
                        + "                    \"*\"\n"
                        + "                ]\n"
                        + "            },\n"
                        + "            \"Action\": [\n"
                        + "                \"s3:GetObject\",\n"
                        + "                \"s3:ListMultipartUploadParts\",\n"
                        + "                \"s3:PutObject\",\n"
                        + "                \"s3:AbortMultipartUpload\",\n"
                        + "                \"s3:DeleteObject\"\n"
                        + "            ],\n"
                        + "            \"Resource\": [\n"
                        + "                \"arn:aws:s3:::%s/**\"\n"
                        + "            ]\n"
                        + "        }\n"
                        + "    ]\n"
                        + "}", bucket, bucket, bucket);
                // 设置策略
                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(policy).build());
            }
        }
    }
    
    
    /**
     * 查看存储bucket是否存在
     */
    private boolean bucketExists(MinioClient minioClient, String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("bucketExists occur exception. e.getMessage() -> {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 创建存储bucket
     */
    private void makeBucket(MinioClient minioClient, String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            throw new MinIOOperateException(String.format("makeBucket %s fail.", bucketName), e);
        }
    }
    
}